﻿using System.Linq;
using System.Web;
using ipFoo.Models;

namespace ipFoo.Helpers
{
    internal static class IpAddress
    {
        /// <summary>
        /// Obtains the IP Address, Host Name, and GeoLocation data for the visiting user
        /// </summary>
        /// <param name="onlyIp">Set to TRUE if you don't want to do a host lookup</param>
        /// <returns></returns>
        internal static IpAddressModel Get(bool onlyIp = false)
        {
            // Setup return
            var response = new IpAddressModel
                               {
                                   IpAddress = Ip(),
                                   HostName = onlyIp ? string.Empty : Host(Ip())
                               };

            return response;
        }

        /// <summary>
        /// Returns the host name for the specified IP Address
        /// </summary>
        /// <param name="ip"></param>
        /// <returns></returns>
        internal static string Host(string ip)
        {
            string hostName;

            // Host name lookups can fail if there isn't an associated host name. Wrap it and tag it.
            try
            {
                hostName = System.Net.Dns.GetHostEntry(ip).HostName;
            }
            catch (System.Net.Sockets.SocketException)
            // SocketException happens when the hostname lookup fails. In this case, simply tell the end user that we have no idea.
            {
                hostName = "Unknown";
            }

            return hostName;
        }

        /// <summary>
        /// Returns the IP Address(es) for the specified host name.
        /// </summary>
        /// <param name="host"></param>
        /// <returns></returns>
        internal static string Ip(string host)
        {
            var hostIps = System.Net.Dns.GetHostAddresses(host);

            return hostIps.Aggregate(string.Empty, (current, ip) => current + string.Format("{0}; ", ip));
        }

        /// <summary>
        /// Obtains the IP Address for the visiting user. Checks for proxy, first.
        /// </summary>
        /// <returns></returns>
        private static string Ip()
        {
            return HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]
                   ?? HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]
                   ?? "Unknown";
        }
    }
}
